package com.code.google.mdsc.io.log.impl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import com.code.google.mdsc.io.log.SimpleLogger;

public class SimpleLoggerImpl implements SimpleLogger {

	private static final SimpleLogger INSTANCE = new SimpleLoggerImpl();
	private static final Properties SYSTEM_CONFIG = new Properties();
	private static LogMode logMode = LogMode.DEBUG;
	private static WriteMode writeMode = WriteMode.BOTH;
	private static File out = new File("log" + System.currentTimeMillis()
			+ ".log");

	static {
		ClassLoader cl = SimpleLoggerImpl.class.getClassLoader();
		try {
			SYSTEM_CONFIG
					.load(cl.getResourceAsStream("com/code/google/mdsc/log.properties"));
			logMode = LogMode.valueOf(SYSTEM_CONFIG.getProperty("LOG_MODE"));

			writeMode = WriteMode.valueOf(SYSTEM_CONFIG
					.getProperty("LOG_WRITE"));
			out = new File(SYSTEM_CONFIG.getProperty("LOG_FILE_NAME")
					+ System.currentTimeMillis() + ".log");
		} catch (Exception e) {
			SimpleLoggerImpl.getInstance().log(LogMode.WARNING, e.getMessage(),
					"Something went wrong, using default values");
		}
	}

	public static SimpleLogger getInstance() {
		return INSTANCE;
	}

	private SimpleLoggerImpl() {
	}

	@Override
	public void log(LogMode logMode, String... log) {
		if (logMode.subsumes(SimpleLoggerImpl.logMode)) {
			StringBuilder sb = new StringBuilder(logMode.name());

			sb.append(" ");
			sb.append(SimpleDateFormat.getDateTimeInstance().format(new Date()));
			sb.append(" ");

			for (String s : log) {
				sb.append(s);
				sb.append(" ");
			}

			write(sb);

		}

	}

	private void write(StringBuilder sb) {
		switch (writeMode) {

		case HARD_DISK:
			writeOnHardDisk(sb);
			break;
		case CONSOLE:
			writeOnConsole(sb);
			break;
		case BOTH:
			writeOnHardDisk(sb);
			writeOnConsole(sb);
			break;
		}

	}

	private void writeOnConsole(StringBuilder sb) {
		System.out.println(sb.toString());
	}

	private void writeOnHardDisk(StringBuilder sb) {

		BufferedWriter bw = null;

		try {
			bw = new BufferedWriter(new FileWriter(out, true));

			bw.write(sb.toString());
			bw.newLine();
		} catch (IOException e) {
			writeMode = WriteMode.CONSOLE;
			INSTANCE.log(LogMode.ERROR,
					"Could not write log to hard disk - switching to CONSOLE mode only.");
		} finally {
			if (bw != null) {
				try {
					bw.close();
				} catch (IOException e) {
					writeMode = WriteMode.CONSOLE;
					INSTANCE.log(LogMode.ERROR,
							"Could not write log to hard disk - switching to CONSOLE mode only.");
				}
			}
		}
	}
}
